package com.projet.segmiMap.model;

import android.util.Log;
import com.google.android.gms.maps.model.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * User: G3_Julien
 * Date: 03/12/13
 * Time: 21:53
 */
public class Etage {
    private int etage;
    private String nom;
    private Set<Lieu> lieux = new HashSet<Lieu>();
    private PolygonOptions coordonnees = new PolygonOptions();
    private Set<Polygon> elements = new HashSet<Polygon>();
    private Set<Marker> markers = new HashSet<Marker>();

    /**
     * Constantes Icones
     */


    public Etage(int niveau, InputStream contour, InputStream salles, InputStream marqueurs) {

        etage = niveau;
        nom = "Etage " + niveau;
        ArrayList<PolygonOptions> contoursLieux;
        ArrayList<MarkerOptions> marqueursLieux;
        coordonnees = creerEtage(contour);
        Log.v("myapp", "Création " + nom);
        contoursLieux = creerLieux(salles);
        Log.v("myapp", "Ajout de " + contoursLieux.size() + " lieux");

        marqueursLieux = creerMarqueurs(marqueurs);
        Log.v("myapp", "Ajout de " + marqueursLieux.size() + " marqueurs");
        for (int i = 0; i < contoursLieux.size(); i++) {
            lieux.add(new Lieu(etage, contoursLieux.get(i), marqueursLieux.get(i)));
        }

    }

    public String getNom() {
        return nom;
    }

    public int getEtage() {
        return etage;
    }

    public PolygonOptions getCoordonnees() {
        return coordonnees;
    }

    public Set<Lieu> getLieux() {
        return lieux;
    }

    public Set<Polygon> getElements() {
        return elements;
    }

    public void setElements(Set<Polygon> elements) {
        this.elements = elements;
    }

    public Set<Marker> getMarkers() {
        return markers;
    }

    public void setMarkers(Set<Marker> markers) {
        this.markers = markers;
    }

    /**
     * Lit chaque noeud coordinates du document KML définissant l'étage
     * puis trace les contours de l'étage en question
     *
     * @param in Le fichier KML de l'étage à créer
     */
    private static final PolygonOptions creerEtage(InputStream in) {
        PolygonOptions coordonnees = new PolygonOptions();
        try {
            DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = documentBuilder.parse(in);

            NodeList listeNoeud = document.getElementsByTagName("coordinates");
            if (listeNoeud.getLength() > 0) {
                Node noeud = listeNoeud.item(0);

                String contenu = noeud.getTextContent();
                String[] coord = contenu.split(" ");
                for (int i = 0; i < coord.length; i++) {
                    String[] latlng = coord[i].split(",");
                    double longitude = Double.parseDouble(latlng[0]);
                    double latitude = Double.parseDouble(latlng[1]);
                    coordonnees.add(new LatLng(latitude, longitude));
                }
            }

        } catch (ParserConfigurationException e) {
            Log.v("myapp", e.getMessage());
        } catch (SAXException e) {
            Log.v("myapp", e.getMessage());
        } catch (IOException e) {
            Log.v("myapp", e.getMessage());
        }
        return coordonnees;
    }

    /**
     * Lit chaque noeud coordinates du document KML définissant les salles d'un étage
     * puis trace les contours des salles en question
     *
     * @param in Le fichier KML des salles à créer
     */
    private static final ArrayList<PolygonOptions> creerLieux(InputStream in) {
        ArrayList<PolygonOptions> lieux = new ArrayList<PolygonOptions>();
        try {
            DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = documentBuilder.parse(in);

            NodeList listeNoeudC = document.getElementsByTagName("coordinates");
            for (int i = 0; i < listeNoeudC.getLength(); i++) {
                Node noeudC = listeNoeudC.item(i);

                String ligneCoord = noeudC.getTextContent();
                String[] coord = ligneCoord.split(" ");
                PolygonOptions coordonnees = new PolygonOptions();
                for (int j = 0; j < coord.length; j++) {

                    String[] latlng = coord[j].split(",");
                    double longitude = Double.parseDouble(latlng[0]);
                    double latitude = Double.parseDouble(latlng[1]);
                    coordonnees.add(new LatLng(latitude, longitude));
                }

                lieux.add(coordonnees);
            }

        } catch (ParserConfigurationException e) {
            Log.v("myapp", e.getMessage());
        } catch (SAXException e) {
            Log.v("myapp", e.getMessage());
        } catch (IOException e) {
            Log.v("myapp", e.getMessage());
        }
        return lieux;
    }

    /**
     * Lit chaque noeud coordinates name et description du document KML définissant les marqueurs d'un étage
     * puis construit les marqueurs en question
     *
     * @param in Le fichier KML des marqueurs à créer
     */
    private static final ArrayList<MarkerOptions> creerMarqueurs(InputStream in) {
        ArrayList<MarkerOptions> marqueurs = new ArrayList<MarkerOptions>();
        try {
            DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = documentBuilder.parse(in);

            NodeList listeNoeudC = document.getElementsByTagName("coordinates");
            NodeList listeNoeudName = document.getElementsByTagName("name");
            NodeList listeNoeudDescription = document.getElementsByTagName("description");

            for (int i = 0; i < listeNoeudC.getLength(); i++) {
                Node noeudC = listeNoeudC.item(i);
                Node noeudName = listeNoeudName.item(i);
                Node noeudDescription = null;
                try {
                    noeudDescription = listeNoeudDescription.item(i);
                } catch (Exception e) {

                }


                String ligneCoord = noeudC.getTextContent();
                String[] coord = ligneCoord.split(",");
                String name = noeudName.getTextContent();
                String description = null;
                if (noeudDescription != null) {
                    description = noeudDescription.getTextContent();
                }
                MarkerOptions marqueur = new MarkerOptions();
                double longitude = Double.parseDouble(coord[0]);
                double latitude = Double.parseDouble(coord[1]);
                marqueur.position(new LatLng(latitude, longitude));
                marqueur.title(name);
                if (description != null) {
                    marqueur.snippet(description);
                }
                marqueurs.add(marqueur);
            }

        } catch (ParserConfigurationException e) {
            Log.v("myapp", e.getMessage());
        } catch (SAXException e) {
            Log.v("myapp", e.getMessage());
        } catch (IOException e) {
            Log.v("myapp", e.getMessage());
        }
        return marqueurs;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Etage)) return false;

        Etage floor = (Etage) o;

        if (etage != floor.etage) return false;
        if (!coordonnees.equals(floor.coordonnees)) return false;
        if (!lieux.equals(floor.lieux)) return false;
        if (!nom.equals(floor.nom)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = etage;
        result = 31 * result + nom.hashCode();
        result = 31 * result + lieux.hashCode();
        result = 31 * result + coordonnees.hashCode();
        return result;
    }
}
